package com.tanger.common.files;

import io.minio.MinioClient;
import io.minio.PutObjectOptions;
import io.minio.Result;
import io.minio.messages.Item;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>类名称：MinioObject</p>
 * <p>类描述：Minio文件操作</p>
 */
public class MinioObject {

	private static final Logger log = LoggerFactory.getLogger(MinioObject.class);

	private MinioClient client;

	public MinioObject(){
	    // 初始化MinioClient
        try {
            client = new MinioClient(FilesConfig.endpoint, FilesConfig.accessKeyId, FilesConfig.accessKeySecret);
        }catch (Exception e){
            e.printStackTrace();
            log.error("init MinioClient error. ", e);
        }
	}
	
	/**
	 * <p>标题：Minio文件上传 </p>
	 * <p>说明： TODO</p>
	 * @version 1.0  2015年9月5日 下午4:19:31
	 * @param key 文件路径/文件名 (文件路径不存在，则直接文件名。如果有重复，则直接覆盖）
	 * @param filePath 要上传的文件路径
	 * @return	true：文件上传成功	false:文件上传失败
	 */
	public boolean putObject(String key, String filePath) {
		try{
            InputStream in = new  FileInputStream(new File(filePath));
            client.putObject(FilesConfig.bucketName, key, in, new PutObjectOptions(in.available(), -1));
            in.close();
		}catch(Exception e){
			e.printStackTrace();
			log.error("=====================上传文件至Minio：", e);
			return false;
		}
		return true;
	}

	/**
	 * 上传文件
	 *
	 * @param key    文件路径，带路径和文件名称
	 * @param in     文件流
	 * @return boolean
	 */
	public boolean putObject(String key, InputStream in) {
		try {
            client.putObject(FilesConfig.bucketName, key, in, new PutObjectOptions(in.available(), -1));
		} catch (Exception e) {
			log.error("Minio 上传文件 {} 出错: {}", key, e.getMessage());
			return false;
		}
		return true;
	}

	/**
	 * <p>标题：Minio文件上传 </p>
	 * <p>说明： TODO</p>
	 * @version 1.0  2015年9月5日 下午4:19:31
	 * @param key 文件路径/文件名 (文件路径不存在，则直接文件名。如果有重复，则直接覆盖）
	 * @return	true：文件上传成功	false:文件上传失败
	 */
	public boolean putObject(String key, File file) {
		try{
            InputStream in = new  FileInputStream(file);
            client.putObject(FilesConfig.bucketName, key, in, new PutObjectOptions(in.available(), -1));
            in.close();
		}catch(Exception e){
			e.printStackTrace();
			log.error("=====================上传文件至Minio：", e);
			return false;
		}
		return true;
	}


	/**
	 * <p>标题： Minio文件删除</p>
	 * <p>说明： 如果文件存在，则直接删除；如果文件不存在，则不做处理</p>
	 * @version 1.0  2015年9月5日 下午4:38:26
	 * @param key 文件路径/文件名
	 * @return true:文件删除成功	false:文件删除失败
	 */
	public boolean deleteObject(String key){
		try{
            client.removeObject(FilesConfig.bucketName, key);
		}catch(Exception e){
			e.printStackTrace();
			return false;
		}
		return true;
	}

	/**
	 * 获取文件夹下所有的文件
	 * @param srcKey 文件夹信息 (xxx/xxx/)
	 * @return
	 */
	public List<String> getFiles(String srcKey){
		try{
			List<String> files = new ArrayList<>();
			Iterable<Result<Item>> myObjects = client.listObjects(FilesConfig.bucketName, srcKey, false, false);
			for (Result<Item> result : myObjects) {
				Item item = result.get();
				files.add(item.objectName());
			}
			return files;
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
	}


	/**
	 * <p>标题：OSS文件复制</p>
	 * <p>说明： TODO</p>
	 * @version 1.0  2015年9月5日 下午5:21:19
	 * @param srcKey	原文件位置
	 * @param destKey	复制后文件位置
	 * @return	true：成功	false：失败
	 */
	public boolean copyObject(String srcKey, String destKey) {
		try{
			// 拷贝Object
			client.copyObject(FilesConfig.bucketName, srcKey, null, null, FilesConfig.bucketName, destKey, null, null);
		}catch(Exception e){
			e.printStackTrace();
			return false;
		}
		return true;
	}

	/**
	 * <p>标题：OSS文件复制 </p>
	 * <p>说明： 复制成功后删除原文件</p>
	 * @version 1.0  2015年9月5日 下午5:21:19
	 * @param srcKey	原文件位置
	 * @param destKey	复制后文件位置
	 * @return	true：成功	false：失败
	 */
	public boolean copyObjectDel(String srcKey, String destKey) {
		try{
			// 拷贝Object
            client.copyObject(FilesConfig.bucketName, srcKey, null, null, FilesConfig.bucketName, destKey, null, null);
			//删除原文件
            client.removeObject(FilesConfig.bucketName, srcKey);
		}catch(Exception e){
			e.printStackTrace();
			return false;
		}
		return true;
	}
}
